﻿#include <WINSOCK2.H>
#include <stdio.h>
#include <iostream>
#include <windows.h>
//#include "package.h"
#pragma comment (lib,"ws2_32.lib")
using namespace std;
#define BUFFERLENGTH 4096
#define SERVERPORT 8888
char* getByteFromFile(FILE* fp, char buf[], int start, int length) {
	int sign;
	int c;
	int i = 0;
	char set[6];
	c = getc(fp);

	while (!feof(fp) && i < BUFFERLENGTH - 2)//-1
	{
		*(buf + i) = c;
		i++;
		c = getc(fp);
	}
	if (feof(fp))
	{
		set[0] = '0';
		buf[i] = '\0';
	}
	else
	{
		set[0] = '1';
		buf[i] = c;
	}
	buf[i + 1] = '\0';

	int f = 1000;
	for (int j = 1; j < 5; j++)
	{
		set[j] = strlen(buf) / f % 10 + '0';
		f = f / 10;
	}
	set[5] = '\0';
	//cout << "in the function the sendbuf is " << buf << endl;
	//cout << "in the funtion the set/head is" << set << endl;
	return set;
}

DWORD WINAPI serverFunction(LPVOID parameter) {
	//SOCKET acceptSock = (SOCKET)parameter;
	SOCKET* ClientSocket = (SOCKET*)parameter;
	char RecvBuf[BUFFERLENGTH + 1];//接收
	char SendBuf[BUFFERLENGTH + 1];//接收

	strcpy(SendBuf, "hello!");
	printf("Send:%s\n", SendBuf);
	send(*ClientSocket, SendBuf, strlen(SendBuf) + 1, 0);
	memset(SendBuf, 0, sizeof(SendBuf));
	while (1) {
		printf("----------------------------------\n\n");
		int receByt = recv(*ClientSocket, RecvBuf, sizeof(RecvBuf), 0);
		/*int len = recv(acceptSock, receiveBuf, sizeof(receiveBuf) - 1, 0);
		receiveBuf[len] = '\0';
		printf("recv:%s\n", receiveBuf);*/
		if (receByt > 0) {
			cout << "接收到的消息是：" << RecvBuf << "            来自客户端:" << *ClientSocket << endl;
			printf("\n");
			// cout<<receByt<<endl;
		}
		else
		{
			cout << "接收消息结束！客户端离开" << endl;
			printf("\n");
			cout << "----------------------------------" << endl;
			break;
		}
		//将收到数据变为文件名
		FILE* fp;
		if (strcmp(RecvBuf, "") == 0) return -1;
		//查找文件是否存在

		string fileName = RecvBuf;
		//fileName = "F:\\VS代码\\FTP服务器\\备用文件\\" + fileName;
		if ((fp = fopen(fileName.c_str(), "r")) == NULL)
		{
			printf("不能打开文件 %s\n", RecvBuf);

			send(*ClientSocket, "99999", 6, 0);
		}

		else {
			//传输文件
			char* head = (char*)malloc(sizeof(char) * (5 + BUFFERLENGTH + 1));
			do
			{
				memset(SendBuf, 0, sizeof(SendBuf));
				strcpy(head, getByteFromFile(fp, SendBuf, 0, BUFFERLENGTH));
				//printf("SendBuf is %s\n", SendBuf);
				strcat(head, SendBuf);
				//printf("Head is %s\n",head);
				send(*ClientSocket, head, strlen(head) + 1, 0);
				Sleep(40);
			} while (head[0] == '1');
			fclose(fp);
		}
	}

	return 0;

}
int main() {
	system("color f0");
	HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
	WORD wOldColorAttrs;
	CONSOLE_SCREEN_BUFFER_INFO csbiInfo;

	// Save the current color
	GetConsoleScreenBufferInfo(h, &csbiInfo);
	wOldColorAttrs = csbiInfo.wAttributes;

	/*----------------------------------------------------------*/
	WSADATA WSAdata;
	SOCKET listenSock, acceptSock;
	SOCKADDR_IN addr_in;
	WORD versionRequest;
	versionRequest = MAKEWORD(2, 2);
	int err;
	err = WSAStartup(versionRequest, &WSAdata);
	if (err) {
		cout << "Error: WSAStartup()!" << endl;
	}
	if ((listenSock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
	{
		printf("error:  WSASocket()! error_number:%d", WSAGetLastError());
		return 1;
	}
	addr_in.sin_family = AF_INET;
	addr_in.sin_port = htons(SERVERPORT);
	addr_in.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	int n = bind(listenSock, (sockaddr*)&addr_in, sizeof(sockaddr));
	if (n == SOCKET_ERROR)
	{
		printf(" Failed bind() \n");
		return -1;
	}
	listen(listenSock, 20);
	cout << "服务端准备就绪，等待连接请求" << endl;
	SOCKADDR_IN clientsocket;
	int len = sizeof(SOCKADDR);
	cout << "server startup sucessful" << endl;
	while (1) {
		SOCKET* ClientSocket = new SOCKET;
		ClientSocket = (SOCKET*)malloc(sizeof(SOCKET));
		//接收客户端连接请求
		int SockAddrlen = sizeof(sockaddr);
		*ClientSocket = accept(listenSock, 0, 0);
		cout << "一个客户端已连接到服务器，socket是：" << *ClientSocket << endl;
		CreateThread(NULL, 0, &serverFunction, ClientSocket, 0, NULL);
	}
	WSACleanup();//释放资源的操作
	return -1;
}